home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gstrans.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  10.0 KB  |  339 lines

  1. /* Copyright (C) 2000 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gstrans.c,v 1.11 2000/09/19 19:00:32 lpd Exp $ */
  20. /* Implementation of transparency, other than rendering */
  21. #include "gx.h"
  22. #include "gserrors.h"
  23. #include "gstrans.h"
  24. #include "gsutil.h"
  25. #include "gzstate.h"
  26.  
  27. /* ------ Transparency-related graphics state elements ------ */
  28.  
  29. int
  30. gs_setblendmode(gs_state *pgs, gs_blend_mode_t mode)
  31. {
  32. #ifdef DEBUG
  33.     if (gs_debug_c('v')) {
  34.     static const char *const bm_names[] = { GS_BLEND_MODE_NAMES };
  35.  
  36.     dlprintf1("[v](0x%lx)blend_mode = ", (ulong)pgs);
  37.     if (mode >= 0 && mode < countof(bm_names))
  38.         dprintf1("%s\n", bm_names[mode]);
  39.     else
  40.         dprintf1("%d??\n", (int)mode);
  41.     }
  42. #endif
  43.     if (mode < 0 || mode > MAX_BLEND_MODE)
  44.     return_error(gs_error_rangecheck);
  45.     pgs->blend_mode = mode;
  46.     return 0;
  47. }
  48.  
  49. gs_blend_mode_t
  50. gs_currentblendmode(const gs_state *pgs)
  51. {
  52.     return pgs->blend_mode;
  53. }
  54.  
  55. int
  56. gs_setopacityalpha(gs_state *pgs, floatp alpha)
  57. {
  58.     if_debug2('v', "[v](0x%lx)opacity.alpha = %g\n", (ulong)pgs, alpha);
  59.     pgs->opacity.alpha = (alpha < 0.0 ? 0.0 : alpha > 1.0 ? 1.0 : alpha);
  60.     return 0;
  61. }
  62.  
  63. float
  64. gs_currentopacityalpha(const gs_state *pgs)
  65. {
  66.     return pgs->opacity.alpha;
  67. }
  68.  
  69. int
  70. gs_setshapealpha(gs_state *pgs, floatp alpha)
  71. {
  72.     if_debug2('v', "[v](0x%lx)shape.alpha = %g\n", (ulong)pgs, alpha);
  73.     pgs->shape.alpha = (alpha < 0.0 ? 0.0 : alpha > 1.0 ? 1.0 : alpha);
  74.     return 0;
  75. }
  76.  
  77. float
  78. gs_currentshapealpha(const gs_state *pgs)
  79. {
  80.     return pgs->shape.alpha;
  81. }
  82.  
  83. int
  84. gs_settextknockout(gs_state *pgs, bool knockout)
  85. {
  86.     if_debug2('v', "[v](0x%lx)text_knockout = %s\n", (ulong)pgs,
  87.           (knockout ? "true" : "false"));
  88.     pgs->text_knockout = knockout;
  89.     return 0;
  90. }
  91.  
  92. bool
  93. gs_currenttextknockout(const gs_state *pgs)
  94. {
  95.     return pgs->text_knockout;
  96. }
  97.  
  98. /* ------ Transparency rendering stack ------ */
  99.  
  100. /*
  101.   This area of the transparency facilities is in flux.  Here is a proposal
  102.   for extending the driver interface.  The material below will eventually
  103.   go in gxdevcli.h.
  104. */
  105.  
  106. /*
  107.   Push the current transparency state (*ppts) onto the associated stack,
  108.   and set *ppts to a new transparency state of the given dimension.  The
  109.   transparency state may copy some or all of the imager state, such as the
  110.   current alpha and/or transparency mask values, and definitely copies the
  111.   parameters.
  112. */
  113. #define dev_t_proc_begin_transparency_group(proc, dev_t)\
  114.   int proc(P6(gx_device *dev,\
  115.     const gs_transparency_group_params_t *ptgp,\
  116.     const gs_rect *pbbox,\
  117.     gs_imager_state *pis,\
  118.     gs_transparency_state_t **ppts,\
  119.     gs_memory_t *mem))
  120. #define dev_proc_begin_transparency_group(proc)\
  121.   dev_t_proc_begin_transparency_group(proc, gx_device)
  122.  
  123. /*
  124.   End a transparency group: blend the top element of the transparency
  125.   stack, which must be a group, into the next-to-top element, popping the
  126.   stack.  If the stack only had a single element, blend into the device
  127.   output.  Set *ppts to 0 iff the stack is now empty.  If end_group fails,
  128.   the stack is *not* popped.
  129. */
  130. #define dev_t_proc_end_transparency_group(proc, dev_t)\
  131.   int proc(P3(gx_device *dev,\
  132.     gs_imager_state *pis,\
  133.     gs_transparency_state_t **ppts))
  134. #define dev_proc_end_transparency_group(proc)\
  135.   dev_t_proc_end_transparency_group(proc, gx_device)
  136.  
  137. /*
  138.   Push the transparency state and prepare to render a transparency mask.
  139.   This is similar to begin_transparency_group except that it only
  140.   accumulates coverage values, not full pixel values.
  141. */
  142. #define dev_t_proc_begin_transparency_mask(proc, dev_t)\
  143.   int proc(P6(gx_device *dev,\
  144.     const gs_transparency_mask_params_t *ptmp,\
  145.     const gs_rect *pbbox,\
  146.     gs_imager_state *pis,\
  147.     gs_transparency_state_t **ppts,\
  148.     gs_memory_t *mem))
  149. #define dev_proc_begin_transparency_mask(proc)\
  150.   dev_t_proc_begin_transparency_mask(proc, gx_device)
  151.  
  152. /*
  153.   Store a pointer to the rendered transparency mask into *pptm, popping the
  154.   stack like end_group.  Normally, the client will follow this by using
  155.   rc_assign to store the rendered mask into pis->{opacity,shape}.mask.  If
  156.   end_mask fails, the stack is *not* popped.
  157. */
  158. #define dev_t_proc_end_transparency_mask(proc, dev_t)\
  159.   int proc(P2(gx_device *dev,\
  160.     gs_transparency_mask_t **pptm))
  161. #define dev_proc_end_transparency_mask(proc)\
  162.   dev_t_proc_end_transparency_mask(proc, gx_device)
  163.  
  164. /*
  165.   Pop the transparency stack, discarding the top element, which may be
  166.   either a group or a mask.  Set *ppts to 0 iff the stack is now empty.
  167. */
  168. #define dev_t_proc_discard_transparency_layer(proc, dev_t)\
  169.   int proc(P2(gx_device *dev,\
  170.     gs_transparency_state_t **ppts))
  171. #define dev_proc_discard_transparency_layer(proc)\
  172.   dev_t_proc_discard_transparency_layer(proc, gx_device)
  173.  
  174.      /* (end of proposed driver interface extensions) */
  175.  
  176. gs_transparency_state_type_t
  177. gs_current_transparency_type(const gs_state *pgs)
  178. {
  179.     return (pgs->transparency_stack == 0 ? 0 :
  180.         pgs->transparency_stack->type);
  181. }
  182.  
  183. /* Support for dummy implementation */
  184. gs_private_st_ptrs1(st_transparency_state, gs_transparency_state_t,
  185.             "gs_transparency_state_t", transparency_state_enum_ptrs,
  186.             transparency_state_reloc_ptrs, saved);
  187. private int
  188. push_transparency_stack(gs_state *pgs, gs_transparency_state_type_t type,
  189.             client_name_t cname)
  190. {
  191.     gs_transparency_state_t *pts =
  192.     gs_alloc_struct(pgs->memory, gs_transparency_state_t,
  193.             &st_transparency_state, cname);
  194.  
  195.     if (pts == 0)
  196.     return_error(gs_error_VMerror);
  197.     pts->saved = pgs->transparency_stack;
  198.     pts->type = type;
  199.     pgs->transparency_stack = pts;
  200.     return 0;
  201. }
  202. private void
  203. pop_transparency_stack(gs_state *pgs, client_name_t cname)
  204. {
  205.     gs_transparency_state_t *pts = pgs->transparency_stack; /* known non-0 */
  206.     gs_transparency_state_t *saved = pts->saved;
  207.  
  208.     gs_free_object(pgs->memory, pts, cname);
  209.     pgs->transparency_stack = saved;
  210.  
  211. }
  212.  
  213. void
  214. gs_trans_group_params_init(gs_transparency_group_params_t *ptgp)
  215. {
  216.     ptgp->ColorSpace = 0;    /* bogus, but can't do better */
  217.     ptgp->Isolated = false;
  218.     ptgp->Knockout = false;
  219. }
  220.  
  221. int
  222. gs_begin_transparency_group(gs_state *pgs,
  223.                 const gs_transparency_group_params_t *ptgp,
  224.                 const gs_rect *pbbox)
  225. {
  226.     /****** NYI, DUMMY ******/
  227. #ifdef DEBUG
  228.     if (gs_debug_c('v')) {
  229.     static const char *const cs_names[] = {
  230.         GS_COLOR_SPACE_TYPE_NAMES
  231.     };
  232.  
  233.     dlprintf5("[v](0x%lx)begin_transparency_group [%g %g %g %g]\n",
  234.           (ulong)pgs, pbbox->p.x, pbbox->p.y, pbbox->q.x, pbbox->q.y);
  235.     if (ptgp->ColorSpace)
  236.         dprintf1("     CS = %s",
  237.         cs_names[(int)gs_color_space_get_index(ptgp->ColorSpace)]);
  238.     else
  239.         dputs("     (no CS)");
  240.     dprintf2("  Isolated = %d  Knockout = %d\n",
  241.          ptgp->Isolated, ptgp->Knockout);
  242.     }
  243. #endif
  244.     return push_transparency_stack(pgs, TRANSPARENCY_STATE_Group,
  245.                    "gs_begin_transparency_group");
  246. }
  247.  
  248. int
  249. gs_end_transparency_group(gs_state *pgs)
  250. {
  251.     /****** NYI, DUMMY ******/
  252.     gs_transparency_state_t *pts = pgs->transparency_stack;
  253.  
  254.     if_debug1('v', "[v](0x%lx)end_transparency_group\n", (ulong)pgs);
  255.     if (!pts || pts->type != TRANSPARENCY_STATE_Group)
  256.     return_error(gs_error_rangecheck);
  257.     pop_transparency_stack(pgs, "gs_end_transparency_group");
  258.     return 0;
  259. }
  260.  
  261. private int
  262. mask_transfer_identity(floatp in, float *out, void *proc_data)
  263. {
  264.     *out = in;
  265.     return 0;
  266. }
  267. void
  268. gs_trans_mask_params_init(gs_transparency_mask_params_t *ptmp,
  269.               gs_transparency_mask_subtype_t subtype)
  270. {
  271.     ptmp->subtype = subtype;
  272.     ptmp->has_Background = false;
  273.     ptmp->TransferFunction = mask_transfer_identity;
  274.     ptmp->TransferFunction_data = 0;
  275. }
  276.  
  277. int
  278. gs_begin_transparency_mask(gs_state *pgs,
  279.                const gs_transparency_mask_params_t *ptmp,
  280.                const gs_rect *pbbox)
  281. {
  282.     /****** NYI, DUMMY ******/
  283.     if_debug8('v', "[v](0x%lx)begin_transparency_mask [%g %g %g %g]\n\
  284.       subtype = %d  has_Background = %d  %s\n",
  285.           (ulong)pgs, pbbox->p.x, pbbox->p.y, pbbox->q.x, pbbox->q.y,
  286.           (int)ptmp->subtype, ptmp->has_Background,
  287.           (ptmp->TransferFunction == mask_transfer_identity ? "no TR" :
  288.            "has TR"));
  289.     return push_transparency_stack(pgs, TRANSPARENCY_STATE_Mask,
  290.                    "gs_begin_transparency_group");
  291. }
  292.  
  293. int
  294. gs_end_transparency_mask(gs_state *pgs,
  295.              gs_transparency_channel_selector_t csel)
  296. {
  297.     /****** NYI, DUMMY ******/
  298.     gs_transparency_state_t *pts = pgs->transparency_stack;
  299.  
  300.     if_debug2('v', "[v](0x%lx)end_transparency_mask(%d)\n", (ulong)pgs,
  301.           (int)csel);
  302.     if (!pts || pts->type != TRANSPARENCY_STATE_Mask)
  303.     return_error(gs_error_rangecheck);
  304.     pop_transparency_stack(pgs, "gs_end_transparency_mask");
  305.     return 0;
  306. }
  307.  
  308. int
  309. gs_discard_transparency_layer(gs_state *pgs)
  310. {
  311.     /****** NYI, DUMMY ******/
  312.     gs_transparency_state_t *pts = pgs->transparency_stack;
  313.  
  314.     if_debug1('v', "[v](0x%lx)discard_transparency_layer\n", (ulong)pgs);
  315.     if (!pts)
  316.     return_error(gs_error_rangecheck);
  317.     pop_transparency_stack(pgs, "gs_discard_transparency_layer");
  318.     return 0;
  319. }
  320.  
  321. int
  322. gs_init_transparency_mask(gs_state *pgs,
  323.               gs_transparency_channel_selector_t csel)
  324. {
  325.     /****** NYI, DUMMY ******/
  326.     gs_transparency_source_t *ptm;
  327.  
  328.     if_debug2('v', "[v](0x%lx)init_transparency_mask(%d)\n", (ulong)pgs,
  329.           (int)csel);
  330.     switch (csel) {
  331.     case TRANSPARENCY_CHANNEL_Opacity: ptm = &pgs->opacity; break;
  332.     case TRANSPARENCY_CHANNEL_Shape: ptm = &pgs->shape; break;
  333.     default: return_error(gs_error_rangecheck);
  334.     }
  335.     rc_decrement_only(ptm->mask, "gs_init_transparency_mask");
  336.     ptm->mask = 0;
  337.     return 0;
  338. }
  339.